package com.cj.myblog.plugin;

import com.cj.myblog.constants.Constants;
import com.cj.myblog.common.util.SpringContextUtil;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
import java.util.Scanner;

/**
 * @Author: jujun chen
 * @Description: 插件动态注册
 * @Date: 2017/10/29
 */
public class PluginClassRegister {


    public static void register() {
        Class clazz = null;
        Method detectHandlerMethods = null;
        Method unregisterMapping = null;

        ApplicationContext applicationContext = SpringContextUtil.getApplicationContext();
        RequestMappingHandlerMapping handlerMapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping");

        try{
            URL pluginUrl = new File("E:\\javaworkspace\\myblog\\blog\\target\\blog-1.0\\WEB-INF\\lib\\" + "test-1.0-SNAPSHOT.jar").toURI().toURL();
            URLClassLoader classLoader = new URLClassLoader(new URL[]{pluginUrl}, Thread.currentThread().getContextClassLoader());

            clazz = classLoader.loadClass("com.cj.myblog.plugins.test.PluginAdminTest");

            unregisterMapping = ReflectUtils.findDeclaredMethod(handlerMapping.getClass(),"unregisterMapping",new Class[]{Object.class});

            detectHandlerMethods = ReflectUtils.findDeclaredMethod(handlerMapping.getClass(),"detectHandlerMethods",new Class[]{Object.class});

        }catch (Exception e){

        }

        ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
        BeanDefinitionRegistry beanDefinitonRegistry = (BeanDefinitionRegistry) configurableApplicationContext
                .getBeanFactory();

        BeanDefinitionBuilder usersBeanDefinitionBuilder = BeanDefinitionBuilder
                .genericBeanDefinition(clazz);
        usersBeanDefinitionBuilder.setScope("singleton");
        beanDefinitonRegistry.registerBeanDefinition("pluginAdminTest",
                usersBeanDefinitionBuilder.getRawBeanDefinition());



        try {

            detectHandlerMethods.setAccessible(true);
            detectHandlerMethods.invoke(handlerMapping,new Object[]{"pluginAdminTest"});
        } catch (Exception e) {
            e.printStackTrace();

            try {
                unregisterMapping.invoke(handlerMapping,new Object[]{"pluginAdminTest"});
                detectHandlerMethods.invoke(handlerMapping,new Object[]{"pluginAdminTest"});
            } catch (Exception e1) {
                e1.printStackTrace();
            }

        }


    }

}
